// @ts-nocheck
import { toRaw } from "vue"
import { 查元件api } from 'amtf/api/元件api';
import { ElMessage, ElMessageBox } from 'element-plus'
import { reactive } from 'vue';
import * as util from 'amtf/utils';

export function 取变动单项组(源单项组, 单项组) {
    const 源单项组集 = {}
    源单项组.forEach(item => {
        源单项组集[item.id] = item
    })
    单项组 = toRaw(单项组)
    单项组 = util.深拷贝(单项组)
    let res = 单项组.filter(item => {
        if (!item.id) return true
        const 源单项 = 源单项组集[item.id]
        if (!源单项) return true
        const 变动单项 = 取变动单项_主体(源单项, item)
        // 会直接修改 item 👆
        if (变动单项) {
            // console.log(`有 变动单项 ing👇`)
            // const 是一个 = (变动单项 === item)
            // console.log(`是一个 👉`, 是一个)
            return true
        }
        return false
    })
    if (res.length == 0) {
        res = null
    }
    return res
}

export function 取变动单项(源单项, 单项) {
    单项 = toRaw(单项)
    单项 = util.深拷贝(单项)
    const 变动单项 = 取变动单项_主体(源单项, 单项)
    return 变动单项
}
/**
 对传入的 @单项 直接修改处理， 返回的 @变动单项 就是 处理后的单项 或者为null
 临时id设置为了负值，下面进行了处理，再提交后台👇
处理关联关系，一对一，一对多
 */
export function 取变动单项_主体(源单项, 单项) {
    let 变动单项 = null
    for (const key in 单项) {
        if (!自动维护字段名组.includes(key)) {
            const 当前值 = 单项[key]
            const 源值 = 源单项[key]
            // 一对一关联的情况👇
            if (util.是对象(当前值)) {
                const 变动单项_子 = 取变动单项_主体(源值 || {}, 当前值)
                if (变动单项_子) {
                    if (!变动单项) 变动单项 = 单项
                    变动单项[key] = 变动单项_子
                }
            }
            // 一对多关联的情况👇
            else if (util.是数组包对象(当前值)) {
                const 变动单项_子组 = []
                当前值.forEach(item => {
                    if (!item.hasOwnProperty("id")) {
                        // 如果元素没有 id 属性，直接判定为变动项
                        变动单项_子组.push(item)
                    } else {
                        if (item.id < 0) {
                            delete item["id"]
                            变动单项_子组.push(item)
                        } else {
                            const 源单项_子 = (源值 || []).find(source => source.id === item.id) || {}
                            const 变动单项_子 = 取变动单项_主体(源单项_子, item)
                            if (变动单项_子) {
                                变动单项_子组.push(变动单项_子)
                            }
                        }
                    }
                })
                if (变动单项_子组.length > 0) {
                    if (!变动单项) 变动单项 = 单项
                    变动单项[key] = 变动单项_子组
                }
            } else {
                if (当前值 !== 源值) {
                    if (!变动单项) 变动单项 = 单项
                    变动单项[key] = 当前值
                }
            }
        }
    }
    return 变动单项
}

export function 取单项_仅变动值(源单项, 单项) {
    单项 = toRaw(单项)
    单项 = util.深拷贝(单项)
    const 变动单项 = 取单项_仅变动值_主体(源单项, 单项)
    变动单项.id = 源单项.id
    return 变动单项
}
export function 取单项_仅变动值_主体(源单项, 单项) {
    let 变动单项 = null
    for (const key in 单项) {
        if (!自动维护字段名组.includes(key)) {
            const 当前值 = 单项[key]
            const 源值 = 源单项[key]
            if (util.是对象(当前值)) {
                const 变动单项_子 = 取单项_仅变动值_主体(源值 || {}, 当前值)
                if (变动单项_子) {
                    if (当前值.hasOwnProperty("id")) {
                        变动单项_子.id = 当前值.id
                    }
                    if (!变动单项) 变动单项 = {}
                    变动单项[key] = 变动单项_子
                }
            } else if (util.是数组包对象(当前值)) {
                const 变动单项_子组 = []
                当前值.forEach(item => {
                    if (!item.hasOwnProperty("id")) {
                        // 如果元素没有 id 属性，直接判定为变动项
                        变动单项_子组.push(item)
                    } else {
                        if (item.id < 0) {
                            delete item["id"]
                            变动单项_子组.push(item)
                        } else {
                            const 源单项_子 = (源值 || []).find(source => source.id === item.id) || {}
                            const 变动单项_子 = 取单项_仅变动值_主体(源单项_子, item)
                            if (变动单项_子) {
                                // 保留 id 属性
                                变动单项_子.id = item.id
                                变动单项_子组.push(变动单项_子)
                            }
                        }
                    }
                })
                if (变动单项_子组.length > 0) {
                    if (!变动单项) 变动单项 = {}
                    变动单项[key] = 变动单项_子组
                }
            } else {
                if (当前值 !== 源值) {
                    if (!变动单项) 变动单项 = {}
                    变动单项[key] = 当前值
                }
            }
        }
    }
    return 变动单项
}

export function 取变动单项组_废(源单项组, 单项组) {
    const 源单项组集 = {}
    源单项组.forEach(item => {
        源单项组集[item.id] = item
    })
    单项组 = toRaw(单项组)
    const res = 单项组.filter(item => {
        if (!item.id) return true
        const 源单项 = 源单项组集[item.id]
        if (!源单项) return true
        for (const key in item) {
            if (!自动维护字段名组.includes(key)) {
                if (!是相同否(item[key], 源单项[key])) {
                    console.log(`key 👉`, key)
                    console.log(`item[key] 👉`, item[key])
                    console.log(`源单项[key] 👉`, 源单项[key])
                    return true
                }
            }
        }
        // 如果所有非排除属性值都相同，排除该项
        return false
    })
    return res
}

function 是相同否(obj1, obj2) {
    // 如果两个值严格相等，直接返回 true
    if (obj1 === obj2) return true
    if (obj1 === null || obj2 === null) return false

    // 检查是否都util.是对象或数组
    const areBothObjects = typeof obj1 === "object" && typeof obj2 === "object"
    if (!areBothObjects) return false

    // 检查是否都是数组
    const areBothArrays = Array.isArray(obj1) && Array.isArray(obj2)
    if (areBothArrays) {
        if (obj1.length !== obj2.length) {
            return false
        }
        for (let i = 0; i < obj1.length; i++) {
            if (!是相同否(obj1[i], obj2[i])) {
                return false
            }
        }
        return true
    }

    // 如果不是数组，当作普通对象处理
    const keys1 = Object.keys(obj1)
    const keys2 = Object.keys(obj2)

    if (keys1.length !== keys2.length) return false

    for (const key of keys1) {
        if (!是相同否(obj1[key], obj2[key])) {
            return false
        }
    }

    return true
}

export let 元件集: 元件集
export let 字段集: 字段集

// export const 下一步 = async (详情) => {
//     if (详情.a.变化了) {
//         let res = await 详情.保存()
//         console.log(`保存 res 👉`, res)
//         if (!res) {
//             return false
//         }
//     }
//     let res = await 详情.api.改({ id: 详情.单项.id, 动作: '下一步' })
//     if (res.code === 0) {
//         util.提示()
//         详情.初始化()
//     }
// }


export const 自动维护字段名组 = ["UpdatedAt", "DeletedAt", "CreatedAt", "创建者", "更新者", "删除者"]
// export const 字段集 = reactive({} as 字段集)
export async function 查元件() {
    const res = await 查元件api()
    console.log(`查元件 res 👉`, res)
    if (res.code == 0) {
        元件集 = res.data.元件集
        // util.对象重予(字段集, res.data.字段集)
        字段集 = res.data.字段集
        // console.log(`组件集 👉`, 组件集)
    } else {
        ElMessage({
            type: "error",
            message: "查元件出错" + res,
        })
    }
}

export function 成标题(props, 字段hook, 字段) {
    if (props.标题) {
        return props.标题
    }
    // console.log(`字段hook 👉`, 字段hook)
    // console.log(`字段.名称 👉`, 字段.名称)
    if (字段hook?.[字段.名称]?.标题) {
        return 字段hook[字段.名称].标题
    }
    // if (路由.a.页面类型 == em.页面类型.详情) {
    //   if (字段.详情标题) return 字段.详情标题
    // }
    let res = 字段.标题 ? 字段.标题 : 字段.名称
    return res
}

export function split取元件id(str: string) {
    const sp = str.split(".")
    let res = str
    if (sp.length > 2) {
        res = sp[0] + "." + sp[1]
    }
    return res
}

export function split取最末字符(str: string) {
    const sp = str.split(".")
    return sp[sp.length - 1]
}

export function 取子表显示设置(字段: 字段, 父环境: string) {
    let 显示设置 = {} as 子表显示设置
    switch (父环境) {
        case '独立详情':
            if (字段.子表显示设置_独立详情) {
                显示设置 = 字段.子表显示设置_独立详情
            }
            break;
        case '简化详情':
            if (字段.子表显示设置_简化详情) {
                // console.log(`字段.子表显示设置_简化详情 👉`, 字段.子表显示设置_简化详情)
                显示设置 = 字段.子表显示设置_简化详情
            }
            break;
        case '父表内嵌':
            if (字段.子表显示设置_父表内嵌) {
                显示设置 = 字段.子表显示设置_父表内嵌
            }
            break;
    }
    return 显示设置
}

